package com.salon.modules.app.utils;

import com.salon.common.exception.CustomException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

/**
 * jwt工具类
 */
@Data
@Slf4j
@Component
@ConfigurationProperties(prefix = "salon.jwt")
public class JwtUtils {

    /**
     * token私钥
     */
    private String secret;

    /**
     * 过期时间
     */
    private Long appExpire;

    /**
     * 过期时间
     */
    private Long adminExpire;

    /**
     * 请求头值
     */
    private String header;

    /**
     * 生成jwt token
     */
    public String getAppToken(Long userId) {
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + appExpire * 1000);
        // 生成token
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(String.valueOf(userId))
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    public Claims getClaimByToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret) // 设置标识名
                    .parseClaimsJws(token)  //解析token
                    .getBody();
        } catch (ExpiredJwtException e) {
            log.info("权鉴已经过期 {}", e);
            throw new CustomException(HttpStatus.UNAUTHORIZED.value(), "登录失效，请重新登录");
        } catch (Exception e) {
            log.info("权鉴验证失败 {}", e);
            throw new CustomException(HttpStatus.UNAUTHORIZED.value(), "登录失效，请重新登录");
        }
        return claims;
    }

    /**
     * 生成token字符串的方法
     */
    public String getAdminToken(String id) {
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + adminExpire * 1000);
        // 生成token
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(id)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .claim("id", id)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    /**
     * 判断token是否存在与有效
     */
    public boolean checkToken(String jwtToken) {
        try {
            if (StringUtils.isEmpty(jwtToken)) {
                return false;
            }
            Jwts.parser().setSigningKey(secret).parseClaimsJws(jwtToken);
        } catch (ExpiredJwtException e) {
            log.info("权鉴已经过期 {}", e);
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 根据token获取会员id
     */
    public String getSysUserIdByJwtToken(String jwtToken) {
        Claims claims = getClaimByToken(jwtToken);
        return (String) claims.get("id");
    }

    /**
     * token是否过期
     *
     * @return true：过期
     */
    public boolean isTokenExpired(Date expiration) {
        return expiration.before(new Date());
    }

}
